package com.lej.login.wxLogin

import android.content.Context
import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.map
import androidx.lifecycle.viewModelScope
import com.google.gson.JsonObject
import com.lej.core.base.BaseModel
import com.lej.core.base.BaseViewModel
import com.lej.core.common.PCacheInfo
import com.lej.core.utils.RegexUtils
import com.lej.core.utils.extention.toast
import com.lej.dataservice.club.bean.login.WxLoginRes
import com.lej.dataservice.club.http.*
import com.lej.dataservice.club.http.base.getBody
import com.lej.dataservice.club.http.bean.ResStatus
import com.lej.login.http.loginApiService
import com.lej.wx.wxLogin
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

/**
 *  author: cjq
 *  date  : 2022/12/5 0005
 *  desc  :
 */
const val LOGIN_WX = 0  // 登录主界面  微信登录
const val LOGIN_TEL = 1  // 手机号登录
const val LOGIN_BIND_NAME = 2  // 绑定用户名
const val LOGIN_BIND_TEL = 3  // 手机号绑定

class WxLoginVM : BaseViewModel<BaseModel>() {
    // wx单选框状态
    val wxCheckStatus = MutableLiveData(false)

    // 手机号单选框状态
    val telCheckStatus = MutableLiveData(false)

    // 手机号
    val userPhone = MutableLiveData("")

    // 验证码
    val userVerify = MutableLiveData("")

    // 用户名
    val userName = MutableLiveData("")

    //  发送验证码ui监听
    val sendCodeEvent = MutableLiveData("获取")

    val isEnable = sendCodeEvent.map {
        it == "获取"
    }

    private suspend fun getTelLoginCode(phone: String, state: Int): Boolean {
        showDialog()
        kotlin.runCatching {
            if (state == LOGIN_TEL) {
                loginApiService.getAutoCode(getBody("phone" to phone)).checkData()
            } else {
                loginApiService.getBindAutoCode(getBody("phone" to phone)).checkData()
            }
            dismissDialog()
            "验证码发送成功".toast()
            return true
        }.onFailure {
            it.message.toast()
        }
        dismissDialog()
        return false
    }

    //发送验证码
    suspend fun sendCode(state: Int) {
        //让观察者的数据改变,逻辑从ViewModel层转到View层，在View层的监听则会被调用
        val phone = userPhone.value
        if (phone == null || !RegexUtils.isMobileSimple(phone)) {
            "请输入正确的手机号码！".toast()
            return
        }
        if (getTelLoginCode(phone, state)) {
            sendCodeJob?.cancel()
            sendCodeJob = viewModelScope.launch {
                newCountdown()
            }
        }
    }

    fun stopCode() {
        sendCodeJob?.cancel()
    }

    var loginRes: WxLoginRes? = null

    fun getLoginVideo(versionName: String) = requestMap(map = { get("loginVideo").asString }) {
        loginApiService.configSever(
            listOf("loginVideo"),
            versionName
        )
    }

    suspend fun wechatLogin(code: String): Int? {
        kotlin.runCatching {
            val wxLogin = loginApiService.wxLogin(getBody("code" to code, "channel" to "android"))
            when (wxLogin.code) {
                RESULT_SUCCESS, WX_NOT_BIND -> {
                    loginRes = wxLogin.result
                    PCacheInfo.token = wxLogin.result.login_token?:""
                }
                else -> {
                    wxLogin.message.toast()
                }
            }
            return wxLogin.code
        }.onFailure {
            Log.d("I/RE",it.message?:"")
        }
        return null
    }

    private fun telLoginApi(phone: String, verifyCode: String) = request {
        loginApiService.phoneOnlyLogin(
            getBody("phone" to phone, "verify_code" to verifyCode)
        )
    }

    private fun bindTelApi(phone: String, verifyCode: String, wxCode: String) = request {
        loginApiService.bindPhone(
            getBody("phone" to phone, "verify_code" to verifyCode, "logon_code" to wxCode)
        )
    }

    private fun bindNameApi(name: String) =
        request { loginApiService.updateInfo(getBody("nick" to name)) }

    fun pullWX(context: Context) {
        if (wxCheckStatus.value != true) {
            "请先阅读并同意协议！".toast()
            return
        }
        context.wxLogin()
    }

    fun loginTel(): MutableLiveData<ResStatus<WxLoginRes>>? {
        if (telCheckStatus.value != true) {
            "请先阅读并同意协议！".toast()
            return null
        }
        val phone = userPhone.value
        val verify = userVerify.value
        if (!checkPhoneInvalid(phone, verify)) {
            return null
        }
        return telLoginApi(phone!!, verify!!)
    }

    fun bindName():MutableLiveData<ResStatus<JsonObject>>?{
        val name = userName.value
        if (name.isNullOrEmpty()) {
            "请输入昵称".toast()
            return null
        }
        return bindNameApi(name = name)
    }

    fun bindTel(): MutableLiveData<ResStatus<WxLoginRes>>? {
        val phone = userPhone.value
        val verify = userVerify.value
        if (!checkPhoneInvalid(phone, verify)) {
            return null
        }
        return bindTelApi(phone!!, verify!!, loginRes?.logon_code ?: "")
    }

    private fun checkPhoneInvalid(phone: String?, verify: String?): Boolean {
        if (phone == null || !RegexUtils.isMobileSimple(phone)) {
            "请输入正确的手机号码！".toast()
            return false
        }
        if (verify.isNullOrEmpty()) {
            "请输入验证吗！".toast()
            return false
        }
        return true
    }

    private var sendCodeJob: Job? = null

    private suspend fun newCountdown() {
        for (i in (60 downTo 0)) {
            sendCodeEvent.value = if (i == 0) "获取" else "${i}s"
            delay(1000)
        }
    }
}